home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / g__~1 / gplibs15.zoo / xcursesw.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-01  |  6.0 KB  |  281 lines

  1. /* 
  2. Copyright (C) 1989, 1992 Free Software Foundation
  3.     written by Eric Newton (newton@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef __GNUG__
  18. #pragma implementation
  19. #endif
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <builtin.h>
  23. #include <values.h>
  24. #ifndef _OLD_STREAMS
  25. #include <strstream.h>
  26. #include <ioprivate.h>
  27. #endif
  28. // Include CurseW.h and/or curses.h *after* iostream includes,
  29. // because curses.h defines a clear macro that conflicts with iostream. Sigh.
  30. #include <xcursesw.h>
  31.  
  32. int CursesWindow::count = 0;
  33.  
  34. /*
  35.  * C++ interface to curses library.
  36.  *
  37.  */
  38.  
  39. /*
  40.  * varargs functions are handled conservatively:
  41.  * They interface directly into the underlying 
  42.  * _doscan, _doprnt and/or vfprintf routines rather than
  43.  * assume that such things are handled compatibly in the curses library
  44.  */
  45.  
  46. int CursesWindow::scanw(const char * fmt, ...)
  47. {
  48.   va_list args;
  49.   va_start(args, fmt);
  50. #ifdef VMS
  51.   int result = wscanw(w , fmt , args);
  52. #else /* NOT VMS */
  53.   char buf[BUFSIZ];
  54.   int result = wgetstr(w, buf);
  55.   if (result == OK) {
  56. #ifndef _OLD_STREAMS
  57.     strstreambuf ss(buf, BUFSIZ);
  58.     result = ss.vscan(fmt, args);
  59. #else /* _OLD_STREAMS */
  60. #ifndef HAVE_VSCANF
  61.       FILE b;
  62.       b._flag = _IOREAD|_IOSTRG;
  63.       b._base = buf;
  64.       b._ptr = buf;
  65.       b._cnt = BUFSIZ;
  66.       result = _doscan(&b, fmt, args);
  67. #else /* HAVE_VSCANF */
  68.       result = vsscanf(buf, fmt, args);
  69. #endif /* HAVE_VSCANF */
  70. #endif /* _OLD_STREAMS */
  71.   }
  72. #endif /* !VMS */
  73.   va_end(args);
  74.   return result;
  75. }
  76.  
  77. int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
  78. {
  79.   va_list args;
  80.   va_start(args, fmt);
  81.   char buf[BUFSIZ];
  82.   int result = wmove(w, y, x);
  83.   if (result == OK)
  84. #ifdef VMS
  85.   result=wscanw(w , fmt , args);
  86. #else /* !VMS */
  87.  {
  88.     result = wgetstr(w, buf);
  89.     if (result == OK) {
  90. #ifndef _OLD_STREAMS
  91.     strstreambuf ss(buf, BUFSIZ);
  92.     result = ss.vscan(fmt, args);
  93. #else /* OLD_STREAMS */
  94. #ifndef HAVE_VSCANF
  95.     FILE b;
  96.     b._flag = _IOREAD|_IOSTRG;
  97.     b._base = buf;
  98.     b._ptr = buf;
  99.     b._cnt = BUFSIZ;
  100.     result = _doscan(&b, fmt, args);
  101. #else
  102.     result = vsscanf(buf, fmt, args);
  103. #endif
  104. #endif /* OLD_STREAMS */
  105.   }
  106.   }
  107. #endif /* !VMS */
  108.   va_end(args);
  109.   return result;
  110. }
  111.  
  112. int CursesWindow::printw(const char * fmt, ...)
  113. {
  114.   va_list args;
  115.   va_start(args, fmt);
  116.   char buf[BUFSIZ];
  117. #ifndef _OLD_STREAMS
  118.   strstreambuf ss(buf, BUFSIZ);
  119.   ss.vform(fmt, args);
  120.   ss.sputc(0);
  121. #else /* _OLD_STREAMS */
  122. #ifndef HAVE_VPRINTF
  123.   FILE b;
  124.   b._flag = _IOWRT|_IOSTRG;
  125.   b._ptr = buf;
  126.   b._cnt = BUFSIZ;
  127.   _doprnt(fmt, args, &b);
  128.   putc('\0', &b);
  129. #else
  130.   vsprintf(buf, fmt, args);
  131. #endif
  132. #endif /* _OLD_STREAMS */
  133.   va_end(args);
  134.   return waddstr(w, buf);
  135. }
  136.  
  137.  
  138. int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
  139. {
  140.   va_list args;
  141.   va_start(args, fmt);
  142.   int result = wmove(w, y, x);
  143.   if (result == OK)
  144.   {
  145.     char buf[BUFSIZ];
  146. #ifndef _OLD_STREAMS
  147.     strstreambuf ss(buf, BUFSIZ);
  148.     ss.vform(fmt, args);
  149.     ss.sputc(0);
  150. #else /* _OLD_STREAMS */
  151. #ifndef HAVE_VPRINTF
  152.     FILE b;
  153.     b._flag = _IOWRT|_IOSTRG;
  154.     b._ptr = buf;
  155.     b._cnt = BUFSIZ;
  156.     _doprnt(fmt, args, &b);
  157.     putc('\0', &b);
  158. #else
  159.     vsprintf(buf, fmt, args);
  160. #endif
  161. #endif /* _OLD_STREAMS */
  162.     result = waddstr(w, buf);
  163.   }
  164.   va_end(args);
  165.   return result;
  166. }
  167.  
  168. CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
  169. {
  170.   if (count==0)
  171.     initscr();
  172.  
  173.   w = newwin(lines, cols, begin_y, begin_x);
  174.   if (w == 0)
  175.   {
  176.     (*lib_error_handler)("CursesWindow", "Cannot construct window");
  177.   }
  178.  
  179.   alloced = 1;
  180.   subwins = par = sib = 0;
  181.   count++;
  182. }
  183.  
  184. CursesWindow::CursesWindow(WINDOW* &window)
  185. {
  186.   if (count==0)
  187.     initscr();
  188.  
  189.   w = window;
  190.   alloced = 0;
  191.   subwins = par = sib = 0;
  192.   count++;
  193. }
  194.  
  195. CursesWindow::CursesWindow(CursesWindow& win, int l, int c, 
  196.                            int by, int bx, char absrel)
  197. {
  198.  
  199.   if (absrel == 'r') // relative origin
  200.   {
  201.     by += win.begy();
  202.     bx += win.begx();
  203.   }
  204.  
  205.   // Even though we treat subwindows as a tree, the standard curses
  206.   // library needs the `subwin' call to link to the root in
  207.   // order to correctly perform refreshes, etc.
  208.  
  209.   CursesWindow* root = &win;
  210.   while (root->par != 0) root = root->par;
  211.  
  212.   w = subwin(root->w, l, c, by, bx);
  213.   if (w == 0)
  214.   {
  215.     (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
  216.   }
  217.  
  218.   par = &win;
  219.   sib = win.subwins;
  220.   win.subwins = this;
  221.   subwins = 0;
  222.   alloced = 1;
  223.   count++;
  224. }
  225.  
  226.  
  227. void CursesWindow::kill_subwindows()
  228. {
  229.   for (CursesWindow* p = subwins; p != 0; p = p->sib)
  230.   {
  231.     p->kill_subwindows();
  232.     if (p->alloced)
  233.     {
  234.       if (p->w != 0)
  235.         ::delwin(p->w);
  236.       p->alloced = 0;
  237.     }
  238.     p->w = 0; // cause a run-time error if anyone attempts to use...
  239.   }
  240. }
  241.     
  242. CursesWindow::~CursesWindow() 
  243. {
  244.   kill_subwindows();
  245.  
  246.   if (par != 0)   // Snip us from the parent's list of subwindows.
  247.   {
  248.     CursesWindow * win = par->subwins;
  249.     CursesWindow * trail = 0;
  250.     for (;;)
  251.     {
  252.       if (win == 0)
  253.         break;
  254.       else if (win == this)
  255.       {
  256.         if (trail != 0)
  257.           trail->sib = win->sib;
  258.         else
  259.           par->subwins = win->sib;
  260.         break;
  261.       }
  262.       else
  263.       {
  264.         trail = win;
  265.         win = win->sib;
  266.       }
  267.     }
  268.   }
  269.  
  270.   if (alloced && w != 0) 
  271.     delwin(w);
  272.  
  273.   --count;
  274.   if (count == 0) 
  275.     endwin();
  276.   else if (count < 0) // cannot happen!
  277.   {
  278.     (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
  279.   }
  280. }
  281.